package com.qinggeng.common.exlog;

import com.alibaba.fastjson.JSON;
import com.qinggeng.common.enums.HttpMethod;
import com.qinggeng.common.utils.ServletUtils;
import com.qinggeng.common.utils.StringUtils;
import com.qinggeng.common.utils.ip.IpUtils;
import com.qinggeng.common.utils.spring.SpringUtils;
import com.qinggeng.framework.config.thread.ThreadPoolExecutorUtil;
import com.qinggeng.framework.manager.AsyncManager;
import com.qinggeng.framework.manager.factory.AsyncFactory;
import com.qinggeng.framework.security.LoginUser;
import com.qinggeng.framework.security.service.TokenService;
import com.qinggeng.project.monitor.domain.SysOperLog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@Aspect
@Component
//只记录全部的错误日志
public class WebLogAspect {
    private  static  final  String TITLE="错误信息";
    private static final Logger log = LoggerFactory.getLogger(WebLogAspect.class);


    @Around("execution(public * com.qinggeng.project.system.controller.*.*(..))||execution(public * com.qinggeng.project.api.controller.*.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object returnValue =null;
        try {
            returnValue = joinPoint.proceed();
        } catch (Exception exception) {
            String exMsg=exception.toString();
            SysOperLog operLog = new SysOperLog();
            String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
            operLog.setOperIp(ip);
            operLog.setTitle(TITLE);
            operLog.setStatus(1);
            operLog.setErrorMsg(exMsg);
            operLog.setBusinessType(0);
            operLog.setOperatorType(0);
            LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
            if (loginUser != null)
            {
                operLog.setOperName(loginUser.getUsername());
            }
            operLog.setMethod(className + "." + methodName + "()");

            String params = argsArrayToString(joinPoint.getArgs());
            operLog.setOperParam(params);
            operLog.setJsonResult(JSON.toJSONString(returnValue));
            operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
            //去除无限线程池
            ThreadPoolExecutorUtil.getPoll().execute(AsyncFactory.recordOper(operLog));
            throw exception;
        }
        return returnValue;
    }
    /**
     * 参数拼装
     */
    private String argsArrayToString(Object[] paramsArray)
    {
        String params = "";
        if (paramsArray != null && paramsArray.length > 0)
        {
            for (int i = 0; i < paramsArray.length; i++)
            {
                if (!isFilterObject(paramsArray[i]))
                {
                    Object jsonObj = JSON.toJSON(paramsArray[i]);
                    if (null !=jsonObj){
                        params += jsonObj.toString() + " ";
                    }
                }
            }
        }
        return params.trim();
    }

    /**
     * 判断是否需要过滤的对象。
     *
     * @param o 对象信息。
     * @return 如果是需要过滤的对象，则返回true；否则返回false。
     */
    public boolean isFilterObject(final Object o)
    {
        return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
    }
}

